package com.glodon.paas.document.biz.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.glodon.paas.consts.StringConst;
import com.glodon.paas.document.api.bean.ProjectResource;
import com.glodon.paas.document.biz.ProjectResourceBiz;
import com.glodon.paas.document.constant.DocumentConstant;
import com.glodon.paas.document.dao.FileDao;
import com.glodon.paas.document.dao.ProjectResourceDao;
import com.glodon.paas.document.dao.ProjectRoleDao;
import com.glodon.paas.document.dao.domain.ProjectResourceEntity;
import com.glodon.paas.document.dao.domain.ProjectRoleEntity;

@Repository("projectResourceBiz")
public class ProjectResourceBizImpl implements ProjectResourceBiz {

    @Autowired
    private ProjectResourceDao projectResourceDao;
    
    @Autowired
    private FileDao fileDao;
    @Autowired
    ProjectRoleDao projectRoleDao;

    @Override
    public List<ProjectResourceEntity> loadUserResource(String userId) {
        return projectResourceDao.selectByUser(userId);
    }

    @Override
    public String insertResource(ProjectResourceEntity entity) {
        return projectResourceDao.insert(entity);
    }

//    @Override
//    public List<ProjectResourceEntity> getResourceByFile(String fileId) {
//        return resourceRolePrivilegeDao.selectResourceByFile(fileId);
//    }

    // 获取文件（夹）上合并的权限，r:读，w：写，d：删除，x：进入。i-r：读（继承）i-w:写（继承），i-d:删除（继承），i-x：进入（继承）
    @Override
    public List<ProjectResource> getFileRolePrivileges(String userId, String fileId, boolean inherit) {
        List<ProjectResourceEntity> selfPV = getFileSelfPrivileges(userId, fileId);
        Map<String, Set<String>> pvMap = new HashMap<String, Set<String>>();
        for(ProjectResourceEntity sPV : selfPV){
            if(pvMap.get(sPV.getRoleId()) == null){
                pvMap.put(sPV.getRoleId(), new HashSet<String>());
            }
            String[] pvs = sPV.getPrivileges().split(StringConst.SEPARATOR_COMMA);
            for(String pv : pvs){
                pvMap.get(sPV.getRoleId()).add(pv);
            }
        }
        if(inherit){
            List<ProjectResourceEntity> parentPV = getFileInheritPrivileges(userId, fileId);
            for(ProjectResourceEntity pPV : parentPV){
                if(pvMap.get(pPV.getRoleId()) == null){
                    pvMap.put(pPV.getRoleId(), new HashSet<String>());
                }
                String[] pvs = pPV.getPrivileges().split(StringConst.SEPARATOR_COMMA);
                for(String pv : pvs){
                    // x 进入权限，不可继承
                    if(!DocumentConstant.FILE_ENTER.equals(pv.trim())){
                        pvMap.get(pPV.getRoleId()).add("i-"+pv.trim());
                    }
                }
            }
        }
        
        List<ProjectRoleEntity> roles = projectRoleDao.getRolesByFile(fileId);
        List<ProjectResource> filePV = new ArrayList<ProjectResource>(roles.size());
        for(ProjectRoleEntity role : roles){
            ProjectResource pr = new ProjectResource();
            pr.setFileId(fileId);
            pr.setRole(ProjectRoleEntity.getDto(role));
            if(pvMap.get(role.getId()) != null){
                String[] p = new String[pvMap.get(role.getId()).size()];
                pvMap.get(role.getId()).toArray(p);
                pr.setPrivileges(p);
            }
            filePV.add(pr);
        }
        return filePV;
    }

    public List<ProjectResourceEntity> getFileSelfPrivileges(String userId, String fileId) {
        if(userId == null){
            return projectResourceDao.selectByFile(fileId);
        }
        else{
            return projectResourceDao.selectByUserFile(userId, fileId);
        }
    }

    public List<ProjectResourceEntity> getFileInheritPrivileges(String userId, String fileId) {
        List<ProjectResourceEntity> res = new ArrayList<ProjectResourceEntity>();
        fileId = fileDao.getParentId(fileId);
        while( fileId != null){
            List<ProjectResourceEntity> pv;
            if(userId == null){
                pv = projectResourceDao.selectByFile(fileId);
            }
            else{
                pv = projectResourceDao.selectByUserFile(userId, fileId);
            }
            if(pv != null && pv.size()>0){
                res.addAll(pv);
            }
            fileId = fileDao.getParentId(fileId);
        }
        return res;
    }

    @Override
    public ProjectResourceEntity getResourceByFileRole(String fileId, String roleId) {
        return projectResourceDao.selectByFileRole(fileId, roleId);
    }

    @Override
    public int updateResource(ProjectResourceEntity entity) {
        return projectResourceDao.update(entity);
    }

    @Override
    public Set<String> getFilePrivileges(String userId, String fileId, boolean inherit) {
        Set<String> pvSet = new HashSet<String>();
        List<ProjectResourceEntity> selfPV = getFileSelfPrivileges(userId, fileId);
        if(selfPV.size()>0){
            for(ProjectResourceEntity sPV : selfPV){
                String[] pvs = sPV.getPrivileges().split(StringConst.SEPARATOR_COMMA);
                for(String pv : pvs){
                    if(StringUtils.isNotBlank(pv)){
                        pvSet.add(pv);
                    }
                }
            }
        }
        if(inherit){
            List<ProjectResourceEntity> parentPV = getFileInheritPrivileges(userId, fileId);
            if(parentPV.size()>0){
                for(ProjectResourceEntity pPV : parentPV){
                    String[] pvs = pPV.getPrivileges().split(StringConst.SEPARATOR_COMMA);
                    for(String pv : pvs){
                        // x 进入权限，不可继承
                        if(StringUtils.isNotBlank(pv) && !DocumentConstant.FILE_ENTER.equals(pv.trim())){
                            pvSet.add("i-"+pv.trim());
                        }
                    }
                }
            }
        }
        return pvSet;
    }

    public void setFileDao(FileDao fileDao) {
        this.fileDao = fileDao;
    }

    public void setProjectResourceDao(ProjectResourceDao projectResourceDao) {
        this.projectResourceDao = projectResourceDao;
    }

    public void setProjectRoleDao(ProjectRoleDao projectRoleDao) {
        this.projectRoleDao = projectRoleDao;
    }
}
